package com.shanxia.im.config;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.im.handler.BindHandler;
import com.shanxia.im.handler.SessionClosedHandler;
import com.shanxia.im.handler.cmd.DispatchCmdHandler;
import com.shanxia.im.sdk.server.IMNioSocketAcceptor;
import com.shanxia.im.sdk.server.handler.IMRequestHandler;
import com.shanxia.im.sdk.server.model.IMSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;

@Configuration
public class IMConfig implements IMRequestHandler, ApplicationListener<ApplicationStartedEvent> {

	@Resource
	private ApplicationContext applicationContext;

	private final HashMap<Integer, IMRequestHandler> appHandlerMap = new HashMap<>();


	@Bean(destroyMethod = "destroy")
	public IMNioSocketAcceptor getNioSocketAcceptor(@Value("${cim.app.port}") int port,
													@Value("${cim.websocket.port}") int websocketPort) {

		return new IMNioSocketAcceptor.Builder()
				.setAppPort(port)
				.setOuterRequestHandler(this)
				.build();
	}

	@Override
	public void process(IMSession session, ProtocolDataBase protocolDataBase) {
		
        IMRequestHandler handler = appHandlerMap.get(protocolDataBase.getCmd());
		
		if(handler == null) {return ;}
		
		handler.process(session, protocolDataBase);
		
	}

	/*
	 * springboot启动完成之后再启动im服务的，避免服务正在重启时，客户端会立即开始连接导致意外异常发生.
	 */
	@Override
	public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {

		appHandlerMap.put(2, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(4, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(6, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(8, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(10, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(102, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(104, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(106, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(108, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(110, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(112, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(114, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(202, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(204, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(206, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(208, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(210, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(302, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(304, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(402, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(1002, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1004, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1006, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1008, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1010, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1012, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(1102, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1104, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1108, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(1202, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(1302, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(1402, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1403, applicationContext.getBean(DispatchCmdHandler.class));
		appHandlerMap.put(1407, applicationContext.getBean(DispatchCmdHandler.class));

		appHandlerMap.put(999,applicationContext.getBean(SessionClosedHandler.class));

		applicationContext.getBean(IMNioSocketAcceptor.class).bind();
	}
}